#pragma once

#include "point.h"

namespace gtl
{

namespace geometry
{

template<typename T>
struct size
{
	typedef size<T> size_type;

	T width;
	T height;

	size()
		: width(0)
		, height(0)
	{
	}

	size(T wdth, T hght)
		: width(wdth)
		, height(hght) 
	{
	}

	size(const size& sz)
		: width(sz.width)
		, height(sz.height) 
	{
	}

	template<class Ty>
	explicit size(const size<Ty>& sz)
		: width(sz.width)
		, height(sz.height) 
	{
	}

	template<class Size>
	explicit size(const Size& sz)
		: width(sz.width)
		, height(sz.height) 
	{
	}

	size(const SIZE& sz)
		: width(sz.cx)
		, height(sz.cy) 
	{
	}

#ifdef __AFXWIN_H__
	size(const CSize& sz)
		: width(sz.cx)
		, height(sz.cy) 
	{
	}
#endif

	void set(T wdth, T hght)
	{
		width = wdth;
		height = hght;
	}

	template<class Size>
	bool operator ==(const Size& sz) const
	{
		return width == T(sz.width) && height == T(sz.height);
	}

	template<class Size>
	bool operator !=(const Size& sz) const
	{
		return width != T(sz.width) || height != T(sz.height);
	}

	template<class Size>
	size operator +(const Size& sz) const
	{
		return size(width + sz.width, height + sz.height);
	}

	template<class Size>
	size operator -(const Size& sz) const
	{
		return size(width - sz.width, height - sz.height);
	}

	template<class Size>
	const size& operator +=(const Size& sz)
	{
		width += sz.width;
		height += sz.height;
		return *this;
	}

	template<class Size>
	const size& operator -=(const Size& sz)
	{
		width -= sz.width;
		height -= sz.height;
		return *this;
	}

	template<class Size>
	Size cast() const
	{
		return Size(width, height);
	}

	void clear()
	{
		width = 0;
		height = 0;
	}

	template<class Size>
	const size& operator =(const Size& sz)
	{
		width = sz.width;
		height = sz.height;
		return *this;
	}

	template<class Ty>
	operator size<Ty>() const
	{
		return size<Ty>(width, height);
	}

	operator SIZE() const
	{
		SIZE sz = { width, height };
		return sz;
	}

#ifdef __AFXWIN_H__
	operator CSize() const
	{
		return CSize(width, height);
	}
#endif
}; // end of class size

} // end of namespace geometry

typedef geometry::size<int>		size;
typedef geometry::size<float>	size_f;
typedef geometry::size<double>	size_d;

} // end of namespace gtl
